package com.xuecheng.media.service.impl;

import com.xuecheng.media.mapper.MediaFilesMapper;
import com.xuecheng.media.mapper.MediaProcessHistoryMapper;
import com.xuecheng.media.mapper.MediaProcessMapper;
import com.xuecheng.media.model.po.MediaFiles;
import com.xuecheng.media.model.po.MediaProcess;
import com.xuecheng.media.model.po.MediaProcessHistory;
import com.xuecheng.media.service.MediaFileProcessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;


/**
 * MediaFileProcessService接口实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MediaFileProcessServiceImpl implements MediaFileProcessService {

    private final MediaProcessMapper mediaProcessMapper;

    private final MediaFilesMapper mediaFilesMapper;

    private final MediaProcessHistoryMapper mediaProcessHistoryMapper;

    /**
     * 获取待处理任务
     *
     * @param shardIndex 分片序号
     * @param shardTotal 分片总数
     * @param count      获取记录数
     * @return List<MediaProcess>
     */
    @Override
    public List<MediaProcess> getMediaProcessList(int shardIndex, int shardTotal, int count) {
        // 使用任务的id % 执行器的总数 得到的值为当前分片号 在根据当前值决定哪一个执行器去执行
        return mediaProcessMapper.selectListByShardIndex(shardTotal, shardIndex, count);
    }

    /**
     * 开启一个任务
     *
     * @param id 任务id
     * @return true表示开启成功，false表示开启失败
     */
    @Override
    public boolean startTask(long id) {
        // 使用乐观锁同时去执行一条sql语句 谁执行成功了就获得锁，以此保证业务的幂等性
        int result = mediaProcessMapper.startTask(id);
        return result > 0;
    }

    /**
     * 更新任务的处理结果
     *
     * @param taskId   任务id
     * @param status   任务状态
     * @param fileId   文件id
     * @param url      url
     * @param errorMsg 错误信息
     */
    @Override
    public void saveProcessFinishStatus(Long taskId, String status, String fileId, String url, String errorMsg) {
        // 先根据任务id去查询任务信息
        MediaProcess mediaProcess = mediaProcessMapper.selectById(taskId);
        if (mediaProcess == null) {
            return;
        }

        // 如果任务执行失败
        if (status.equals("3")) {
            // 更新MediaProcess表的状态
            mediaProcess.setStatus("3"); // 设置状态
            mediaProcess.setErrormsg(errorMsg); // 设置错误原因
            mediaProcess.setFailCount(mediaProcess.getFailCount() + 1); // 失败次数加1
            mediaProcessMapper.updateById(mediaProcess);
            return;
            /*LambdaUpdateWrapper<MediaProcess> updateWrapper = new LambdaUpdateWrapper<MediaProcess>()
                    .set(MediaProcess::getStatus, "3")
                    .set(MediaProcess::getErrormsg, errorMsg)
                    .set(MediaProcess::getFailCount, mediaProcess.getFailCount() + 1);
            mediaProcessMapper.update(mediaProcess, updateWrapper);*/
        }

        // 如果任务执行成功  更新media_files表的url字段
        MediaFiles mediaFiles = mediaFilesMapper.selectById(fileId);
        // 更新media_files表的url字段
        mediaFiles.setUrl(url);
        // 执行更新
        mediaFilesMapper.updateById(mediaFiles);

        // 更新MediaProcess表的状态
        mediaProcess.setStatus("2");
        mediaProcess.setFinishDate(LocalDateTime.now());
        mediaProcess.setUrl(url);
        mediaProcessMapper.updateById(mediaProcess);

        // 将MediaProcess表记录插入到media_process_history表中
        MediaProcessHistory mediaProcessHistory = new MediaProcessHistory();
        BeanUtils.copyProperties(mediaProcess, mediaProcessHistory);
        mediaProcessHistoryMapper.insert(mediaProcessHistory);

        // 删除MediaProcess表中记录
        mediaProcessMapper.deleteById(taskId);
    }
}
